package com.kl.config;

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * 微信接口传递过来的是 text/plain 数据，这个转换器用来处理该数据
 * 解决异常
 * Could not extract response: no suitable HttpMessageConverter found for
 * response type [class com.xxx.xx]
 * and content type [text/html;charset=UTF-8]
 * 异常说明：没有合适的messageConverter！这肯定不可能，再定睛一看，content type怎么是text/html，
 * 微信接口文档虽说返回的是 Json 数据，但是同时返回的 Header 里面的 Content-Type 值确是 text/plain 的！
 * 询问了下API提供方，他们居然没在接口返回设置content type，这就导致了明明返回的数据是json数据格式确被识别为text/html
 * 最终结果就是导致 RestTemplate 把数据从 HttpResponse 转换成 Object 的时候，
 * 找不到合适的 HttpMessageConverter 来转换！
 */
@SuppressWarnings("all")
public class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    public WxMappingJackson2HttpMessageConverter(){
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.TEXT_PLAIN);
        setSupportedMediaTypes(mediaTypes);
    }

    /**
     * 一直没搞懂的是为什么添加了mediaTypes.add(MediaType.TEXT_PLAIN)，让该转换器在判断时能够支持text时就能处理
     * 那我随便给这个转换器加一个 MediaType.xxx 它也能处理吗？这里面的逻辑到底是什么
     * 首先需要搞清楚json对象和json字符串的区别
     * 在前后端传递数据的时候，实际上传递的都是json字符串，也就是符合json规范的字符串，
     * RestTemplate内置了对应的转换器能够将这种符合json规范的字符串转换为java对象，就简称为J转换器
     * J转换器需要根据响应的数据类型，也就是content-type判断，是否是application/json格式的数据，如果是就执行转换流程
     * application/json说白了就是一个标志，一个对当前信息的标记而已
     * 调用微信接口时，它虽然传输的也是json字符串，但是它并没有将标记改为对应的application/json，
     * 而就是普通的text/html，所以J转换器就以为自己转换不了，所以没有走转换的流程，
     * 在上面的代码逻辑中我们复制了一个J转换器，并告诉它你可以处理text/html的数据，
     * 本来处理的也是json字符串，所以最后能够成功转换
     *
     * 总结：数据不过就是一些标记而已，不要把数据拟人化，否则总是绕不出错误的逻辑
     */
}
